const lowOrderMatrix = {
  weeks: {
    days: 7,
    hours: 7 * 24,
    minutes: 7 * 24 * 60,
    seconds: 7 * 24 * 60 * 60,
    milliseconds: 7 * 24 * 60 * 60 * 1000,
  },
  days: {
    hours: 24,
    minutes: 24 * 60,
    seconds: 24 * 60 * 60,
    milliseconds: 24 * 60 * 60 * 1000,
  },
  hours: { minutes: 60, seconds: 60 * 60, milliseconds: 60 * 60 * 1000 },
  minutes: { seconds: 60, milliseconds: 60 * 1000 },
  seconds: { milliseconds: 1000 },
};

const casualMatrix = {
  years: {
    quarters: 4,
    months: 12,
    weeks: 52,
    days: 365,
    hours: 365 * 24,
    minutes: 365 * 24 * 60,
    seconds: 365 * 24 * 60 * 60,
    milliseconds: 365 * 24 * 60 * 60 * 1000,
  },
  quarters: {
    months: 3,
    weeks: 13,
    days: 91,
    hours: 91 * 24,
    minutes: 91 * 24 * 60,
    seconds: 91 * 24 * 60 * 60,
    milliseconds: 91 * 24 * 60 * 60 * 1000,
  },
  months: {
    weeks: 4,
    days: 30,
    hours: 30 * 24,
    minutes: 30 * 24 * 60,
    seconds: 30 * 24 * 60 * 60,
    milliseconds: 30 * 24 * 60 * 60 * 1000,
  },

  ...lowOrderMatrix,
};
const daysInYearAccurate = 146097.0 / 400;
const daysInMonthAccurate = 146097.0 / 4800;
const accurateMatrix = {
  years: {
    quarters: 4,
    months: 12,
    weeks: daysInYearAccurate / 7,
    days: daysInYearAccurate,
    hours: daysInYearAccurate * 24,
    minutes: daysInYearAccurate * 24 * 60,
    seconds: daysInYearAccurate * 24 * 60 * 60,
    milliseconds: daysInYearAccurate * 24 * 60 * 60 * 1000,
  },
  quarters: {
    months: 3,
    weeks: daysInYearAccurate / 28,
    days: daysInYearAccurate / 4,
    hours: (daysInYearAccurate * 24) / 4,
    minutes: (daysInYearAccurate * 24 * 60) / 4,
    seconds: (daysInYearAccurate * 24 * 60 * 60) / 4,
    milliseconds: (daysInYearAccurate * 24 * 60 * 60 * 1000) / 4,
  },
  months: {
    weeks: daysInMonthAccurate / 7,
    days: daysInMonthAccurate,
    hours: daysInMonthAccurate * 24,
    minutes: daysInMonthAccurate * 24 * 60,
    seconds: daysInMonthAccurate * 24 * 60 * 60,
    milliseconds: daysInMonthAccurate * 24 * 60 * 60 * 1000,
  },
  ...lowOrderMatrix,
};

/**
 * 将秒数转换为分钟数，不足1分钟时按1分钟计算
 * @param {number|string} seconds - 秒数
 * @returns {number} - 转换后的分钟数（最小值为1，无效值返回0）
 */
function secondsToMinutes(seconds?: number | string): number {
  // 处理空值或未定义
  if (seconds === undefined || seconds === null || seconds === '') {
    return 0;
  }

  // 尝试将输入转换为数字
  const parsedSeconds =
    typeof seconds === 'string' ? parseFloat(seconds) : Number(seconds);

  // 处理非数字或负数输入
  if (Number.isNaN(parsedSeconds) || parsedSeconds < 0) {
    return 0;
  }

  // 计算分钟数，向上取整（不足1分钟按1分钟算）
  return Math.max(1, Math.ceil(parsedSeconds / 60));
}

/**
 * 使用指定矩阵格式化分钟数为可读的字符串，如 "1年2个月3天"
 * @param {number} minutes - 需要转换的分钟数
 * @param {boolean} accurate - 是否使用精确模式（默认 false 使用 casualMatrix）
 * @returns {string}
 */
function formatMinutesToYMDHM(mins: number, accurate = false): string {
  if (!mins) return '';

  const matrix = (accurate ? accurateMatrix : casualMatrix) as IData;
  const totalMs = mins * 60 * 1000;
  let remainingMs: number = totalMs;

  const result = {
    years: 0,
    months: 0,
    days: 0,
    hours: 0,
    minutes: 0,
  } as IData;

  const units = ['years', 'months', 'days', 'hours', 'minutes'];
  units.forEach(unit => {
    const unitMs =
      matrix[unit]?.milliseconds ?? (matrix[unit]?.minutes ?? 0) * 60 * 1000;

    if (!unitMs) return;

    result[unit] = Math.floor(remainingMs / unitMs);
    // eslint-disable-next-line operator-assignment
    remainingMs = remainingMs % unitMs;
  });
  // 构造文本格式（按规则裁剪）
  const labels = {
    years: '年',
    months: '个月',
    days: '天',
    hours: '小时',
    minutes: '分钟',
  } as IData;

  // 找第一个非零单位的索引
  const firstNonZeroIndex = units.findIndex(u => result[u] > 0);
  if (firstNonZeroIndex === -1) {
    return '0分钟';
  }

  const parts = units
    .slice(firstNonZeroIndex)
    .map(unit => {
      const value = result[unit];
      return value > 0 ? `${value}${labels[unit]}` : '';
    })
    .filter(Boolean); // 过滤空字符串

  return parts.join('、');
}

/**
 * 将秒数转换并格式化为年月日时分的描述
 * @param {number|string} seconds - 秒数
 * @returns {string} - 格式化后的时间描述
 */
function formatSecondsToDateTime(seconds: number, accurate = false): string {
  const minutes = secondsToMinutes(seconds);
  return formatMinutesToYMDHM(minutes, accurate);
}

export { formatSecondsToDateTime };
